package models

import (
	"errors"
	"gitee.com/sansaniot/ssiot-core/httpmvc/model"
	"gorm.io/gorm"
	dto "ssadmin/common/query"
	"ssadmin/common/utils"
	"ssadmin/internal/admin/models/query"
	"time"
)

type UserApp struct {
	AppId   string `json:"appId"`
	AppName string `json:"appName"`

	CreateTimeDts *time.Time `json:"-" gorm:"column:create_time;"`
	CreateTime    string     `json:"createTime" gorm:"-"`
	ExpireTimeDts *time.Time `json:"-" gorm:"column:expire_time;"`
	ExpireTime    string     `json:"expireTime" gorm:"-"`
	ModifyTimeDts *time.Time `json:"-" gorm:"column:update_time;"`
	ModifyTime    string     `json:"modifyTime" gorm:"-"`

	Creator   string `json:"creator"`
	CreatorId string `json:"creatorId"`
	Status    string `json:"status"`

	AppToken string   `json:"appToken" gorm:"-"`
	ApiList  []string `json:"apiList" gorm:"-"`
	model.Model
}

func (UserApp) TableName() string {
	return "sys_user_app"
}

// GetPage 获取应用列表
func (u *UserApp) GetPage(db *gorm.DB, c *query.UserAppQuery, list *[]UserApp, count *int64) error {
	where := make([]func(db *gorm.DB) *gorm.DB, 0)

	if len(c.Status) > 0 {
		where = append(where, func(db *gorm.DB) *gorm.DB {
			return db.Where("status = ?", c.Status)
		})
	}

	if len(c.Search) > 0 {
		where = append(where, func(db *gorm.DB) *gorm.DB {
			return db.Where("app_id ilike ? or app_name ilike ?", "%"+c.Search+"%", "%"+c.Search+"%")
		})
	}

	//是否存在对应的租户id(admin查询所有)
	if len(c.AgentId) > 0 {
		where = append(where, func(db *gorm.DB) *gorm.DB {
			return db.Where("creator_id = ?", c.AgentId)
		})
	}

	where = append(where, dto.OrderDest("create_time", true))
	where = append(where, dto.Paginate(c.GetPageSize(), c.GetPageIndex()))

	//Joins("JOIN t_user_dept ud ON ud.user_id = t_user.user_id AND ud.dept_id IN (?)", deptIds).
	err := db.Model(&UserApp{}).Scopes(where...).Find(list).Limit(-1).Offset(-1).Count(count).Error

	for i, _ := range *list {
		//获取当前对象
		userApp := (*list)[i]
		//格式处理
		formatAppInfo(&userApp)
		//重新设置
		(*list)[i] = userApp
	}

	return err
}

//获取应用明细
func (u *UserApp) GetDetail(c *query.UserAppGetReq) error {
	q := query.UserAppDbParam{AppId: c.AppId}
	where := dto.MakeCondition(q)
	err := u.Orm.Model(u).Scopes(where).First(u).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil
	}
	//格式处理
	formatAppInfo(u)

	//关联查询当前应用id对应的api集合
	apiList := make([]string, 0)
	_ = u.Orm.Table(UserAppApi{}.TableName()+" ur").Select("ur.api_path").Where("ur.app_id = ?", u.AppId).Scan(&apiList).Error
	//缓存应用关联的api集合
	u.ApiList = apiList

	return nil
}

func (u *UserApp) Add(db *gorm.DB, data *UserApp) (err error) {
	err = db.Model(&UserApp{}).Create(data).Error
	return err
}

func (UserApp) Mod(db *gorm.DB, data interface{}, condition ...func(db *gorm.DB) *gorm.DB) (err error) {
	tx := db.Model(&UserApp{}).
		Scopes(condition...).
		Updates(data)
	if tx.RowsAffected == 0 {
		return errors.New("修改失败")
	}
	return tx.Error
}

func (u *UserApp) DelByAppIds(db *gorm.DB, appIdList []string) {
	//数据删除
	ud := UserApp{}
	db.Model(&ud).Where("app_id in (?)", appIdList).Delete(ud)
}

func formatAppInfo(info *UserApp) {
	//时间同步处理
	if info.CreateTimeDts != nil {
		info.CreateTime = info.CreateTimeDts.Format(utils.TIME_FMT_FULL)
	}
	if info.ExpireTimeDts != nil {
		info.ExpireTime = info.ExpireTimeDts.Format(utils.TIME_FMT_FULL)
	}
	if info.ModifyTimeDts != nil {
		info.ModifyTime = info.ModifyTimeDts.Format(utils.TIME_FMT_FULL)
	}

	//必须启用才可以存在token(就算过期也可以创建 只是无效)
	if info.Status != "0" && info.ExpireTimeDts != nil {
		//获取当前过期的时间
		expTime := info.ExpireTimeDts.Unix()
		//创建token
		info.AppToken = utils.GetCommUtil().GenUserAppToken(info.AppId, info.Creator, expTime)
	}
}
